/**
 * 
 */
package com.kelaite.procurement.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kelaite.procurement.constants.Constants;
import com.kelaite.procurement.dto.CompanyDTO;
import com.kelaite.procurement.dto.MaterialMasterClientDTO;
import com.kelaite.procurement.entity.TCompany;
import com.kelaite.procurement.entity.TMaterialMasterClient;
import com.kelaite.procurement.exception.DuplicateObjectException;
import com.kelaite.procurement.exception.NullObjectException;
import com.kelaite.procurement.repository.CompanyRepository;
import com.kelaite.procurement.repository.MaterialMasterClientRepository;
import com.kelaite.procurement.service.MaterialMasterClientService;
import com.kelaite.procurement.utils.ConvertUtil;
import com.kelaite.procurement.utils.CurrentUserUtils;

@Service
@Transactional
public class MaterialMasterClientServiceImpl implements
		MaterialMasterClientService {

	private static final Logger logger = Logger
			.getLogger(MaterialMasterClientServiceImpl.class);

	@Autowired
	private MaterialMasterClientRepository materialMasterClientRepository;

	@Autowired
	private CompanyRepository companyRepository;

	@PersistenceContext
	private EntityManager em;

	@Override
	public TMaterialMasterClient save(TMaterialMasterClient persistence) {

		return materialMasterClientRepository.save(persistence);
	}

	@Override
	public void deleteByPrimaryKey(Long id) {

		materialMasterClientRepository.delete(id);

	}

	@Override
	public void deleteByObject(TMaterialMasterClient persistence) {

		materialMasterClientRepository.delete(persistence);

	}

	@Override
	public TMaterialMasterClient getObject(Long id) {

		return materialMasterClientRepository.findOne(id);
	}

	@Override
	public List<TMaterialMasterClient> getAll() {

		return materialMasterClientRepository.findAll();
	}

	@SuppressWarnings({ "deprecation", "unchecked" })
	@Override
	public List<TMaterialMasterClient> getByProperty(String property,
			Object value) {

		Session session = (org.hibernate.Session) em.getDelegate();
		Criteria criteria = session.createCriteria(TMaterialMasterClient.class)
				.add(org.hibernate.criterion.Expression.eq(property, value));
		return criteria.list();
	}

	@Override
	public List<TMaterialMasterClient> getListByCompany(CompanyDTO companyDTO) {

		if (null == companyDTO) {
			throw new NullObjectException("CompanyDTO is null. ");
		}
		TCompany tCompany = ConvertUtil.convertObj(companyDTO, TCompany.class);
		//
		return materialMasterClientRepository.findByTCompany(tCompany);
	}

	@Override
	public MaterialMasterClientDTO addMaterialMasterClient(
			MaterialMasterClientDTO materialMasterClientDTO) {

		if (null == materialMasterClientDTO) {
			throw new NullObjectException("MaterialMasterClientDTO is null. ");
		}
		String materialName = materialMasterClientDTO.getMaterialName();
		if (StringUtils.isBlank(materialName)) {
			throw new NullObjectException(
					"MaterialMasterClientDTO.materialName is null. ");
		}
		// CompanyId
		Long companyId = CurrentUserUtils.getInstance().getUser().gettCompany()
				.getId();
		//
		// check repeat
		int cnt = materialMasterClientRepository
				.countByMaterialNameAndCompanyId(materialName, companyId);
		if (cnt > 0) {
			String msg = String.format("Material named[%s] exsist. ",
					materialName);
			logger.error(msg);
			throw new DuplicateObjectException(msg);
		}
		//
		// TCompany
		TCompany dbCompany = companyRepository.findOne(companyId);
		//
		TMaterialMasterClient dbMaterialMasterClient = ConvertUtil.convertObj(
				materialMasterClientDTO, TMaterialMasterClient.class);
		dbMaterialMasterClient.settCompany(dbCompany);
		dbMaterialMasterClient.setStatus(Constants.UN_AUDITED);
		dbMaterialMasterClient = materialMasterClientRepository
				.save(dbMaterialMasterClient);
		return ConvertUtil.convertObj(dbMaterialMasterClient,
				MaterialMasterClientDTO.class);
	}
}
